# TOPNAME and VERILATOR_CFLAGS is defined in subdirectories
NXDC_FILES = constr/$(TOPNAME).nxdc
INC_PATH ?=

VERILATOR = verilator
VERILATOR_CFLAGS += -cc --build -trace

NVB_VERILATOR_CFLAGS += -MMD --build -cc  \
				-O3 --x-assign fast --x-initial fast --noassert

# normal verilator build
BUILD_DIR = ./build
OBJ_DIR = $(BUILD_DIR)/obj_dir
BIN = $(BUILD_DIR)/$(TOPNAME)

# verilator build with nvboard
NVB_BUILD_DIR = ./nvboard
NVB_OBJ_DIR = $(NVB_BUILD_DIR)/obj_dir
NVB_BIN = $(NVB_OBJ_DIR)/$(TOPNAME)

$(shell mkdir -p $(BUILD_DIR))
$(shell mkdir -p $(NVB_BUILD_DIR))

default: waveform.vcd

# constraint file
SRC_AUTO_BIND = $(abspath $(NVB_BUILD_DIR)/auto_bind.cpp)
$(SRC_AUTO_BIND): $(NXDC_FILES)
	python3 $(NVBOARD_HOME)/scripts/auto_pin_bind.py $^ $@

# project source
VSRCS = $(shell find $(abspath ./vsrc) -name "*.v" -or -name "*.sv")
CSRCS = $(shell find $(abspath ./csrc) -name "*.c" -or -name "*.cc" -or -name "*.cpp")
NVB_CSRCS = $(shell find $(abspath ./nvcsrc) -name "*.c" -or -name "*.cc" -or -name "*.cpp")
NVB_CSRCS += $(SRC_AUTO_BIND)

# rules for NVBoard
include $(NVBOARD_HOME)/scripts/nvboard.mk

# rules for verilator
INCFLAGS = $(addprefix -I, $(INC_PATH))
CXXFLAGS += $(INCFLAGS) -DTOP_NAME="\"V$(TOPNAME)\""

build: $(BIN)

waves: waveform.vcd
	@echo
	@echo "### WAVES ###"
	gtkwave waveform.vcd

waveform.vcd: $(BIN)
	@echo
	@echo "### SIMULATING ###"
	@$^ +verilator+rand+reset+2

$(BIN): $(VSRCS) $(CSRCS)
	@echo
	@echo "### BUILDING SIM ###"
	$(VERILATOR) $(VERILATOR_CFLAGS) \
		--top-module $(TOPNAME) $^ \
		--exe --Mdir $(OBJ_DIR) -o $(abspath $(BIN))

$(NVB_BIN): $(VSRCS) $(NVB_CSRCS) $(NVBOARD_ARCHIVE)
	@rm -rf $(NVB_OBJ_DIR)
	$(VERILATOR) $(NVB_VERILATOR_CFLAGS) \
		--top-module $(TOPNAME) $^ \
		$(addprefix -CFLAGS , $(CXXFLAGS)) $(addprefix -LDFLAGS , $(LDFLAGS)) \
		--Mdir $(NVB_OBJ_DIR) --exe -o $(abspath $(NVB_BIN))

run: $(NVB_BIN)
	@$^

lint: $(VSRCS)
	verilator --lint-only $(VSRCS)

create:
	@./createproj.sh

all: default

clean:
	rm -rf $(BUILD_DIR)
	rm -rf $(NVB_BUILD_DIR)
	rm -f waveform.vcd

.PHONY: all default build waves run lint create clean
